//
//  BlockTest.m
//  MacTestProject
//
//  Created by LiuLichen on 2022/4/15.
//

// reference: fuckingblocksyntax.com

#import "BlockTest.h"

typedef int (^BlockDef) (BOOL flag, int val);

@implementation BlockTest

- (id) init {
    self = [super init];

    NSString* (^blockFunc1)(NSString*) = ^(NSString* param) {
        NSLog(@"%@", param);
        return @"blockFunc1";
    };
    NSLog(@"%@", blockFunc1(@"param"));

    self.blockFunc2 = ^NSString* _Nonnull(NSString* _Nonnull param) {
        NSLog(@"%@", param);
        return @"blockFunc2";
    };
    NSLog(@"%@", self.blockFunc2(@"param"));

    BlockDef blockFunc3 = ^(BOOL flag, int val) {
        if (flag) {
            return val * 2;
        } else {
            return val * 5;
        }
    };
    blockFunc3(YES, 2);
    blockFunc3(NO, 2);

    [self testBlockCopy];

    return self;
}

- (void) testBlockCopy {
    typedef void (^blk_t)(id);

    blk_t blk;

    // block1
    {
        id array = [[NSMutableArray alloc] init];
        blk = [^(id obj) {
            [array addObject:obj];
            NSLog(@"array count = %ld", [array count]);
        } copy];
    }
    // block2
//    {
//        id array = [[NSMutableArray alloc] init];
//        blk = ^(id obj) {
//            [array addObject:obj];
//            NSLog(@"array count = %ld", [array count]);
//        };
//    }
    // block3
//    {
//        id array = [[NSMutableArray alloc] init];
//        id __weak array2 = array;
//        blk = [^(id obj) {
//            [array2 addObject:obj];
//            NSLog(@"array2 count = %ld", [array2 count]);
//        } copy];
//    }

    blk([[NSObject alloc] init]);
    blk([[NSObject alloc] init]);
    blk([[NSObject alloc] init]);
    /**
     * for block1, should output "array count = 1,2,3" as the result because the blk is allocated on the heap.
     * for block2, should crash when running "blk([[NSObject alloc] init]);" because the blk is allocated on the stack, and will be released at the end of the block.
     * for block3, should output "array2 count = 0,0,0" as the result because the strong pointer array will be release at the end of the block, and will assign nil to its corresponding weak pointer array2.
     */
}

@end
